package midend;

import midend.IR_Value.IR_BaseBlock;
import midend.IR_Value.IR_Value;
import java.util.List;
import java.util.Set;
import java.util.ArrayList;
import java.util.HashSet;

public class Loop {
    private final IR_BaseBlock loopHeader;
    private final List<IR_BaseBlock> loopBody = new ArrayList<>(); // 循环所有基本块，包括header
    private Loop parentLoop;
    private final Set<Loop> childLoops = new HashSet<>();
    // private final List<IR_BaseBlock> loopExit = new ArrayList<>();

    // 迭代信息字段
    private IR_Value itBegin; // 循环开始值
    private IR_Value itVar; // 循环变量（Phi指令）
    private IR_Value itEnd; // 循环结束值
    private IR_Value itAlu; // 迭代计算指令
    private IR_Value itChange; // 迭代步长值
    private IR_Value itCmp; // 比较指令
    private String op; // 迭代操作符（ADD、SUB、MUL等）
    private boolean isUseLess; // 是否为无用循环

    public void setLoopIterator(IR_Value itBegin, IR_Value itCmp, IR_Value itVar,
            IR_Value itEnd, String op, IR_Value itAlu,
            IR_Value itChange, boolean isUseLess) {
        this.itBegin = itBegin;
        this.itCmp = itCmp;
        this.itVar = itVar;
        this.itEnd = itEnd;
        this.op = op;
        this.itAlu = itAlu;
        this.itChange = itChange;
        this.isUseLess = isUseLess;
    }

    public IR_Value getItBegin() {
        return itBegin;
    }

    public IR_Value getItVar() {
        return itVar;
    }

    public IR_Value getItEnd() {
        return itEnd;
    }

    public IR_Value getItAlu() {
        return itAlu;
    }

    public IR_Value getItChange() {
        return itChange;
    }

    public IR_Value getItCmp() {
        return itCmp;
    }

    public String getOp() {
        return op;
    }

    public boolean isUseLess() {
        return isUseLess;
    }

    public Loop(IR_BaseBlock loopHeader) {
        this.loopHeader = loopHeader;
        addLoopBody(loopHeader);
    }

    public void addLoopBody(IR_BaseBlock loopBody) {
        this.loopBody.add(loopBody);
    }

    public void addChildLoop(Loop childLoop) {
        this.childLoops.add(childLoop);
    }

    public Set<Loop> getChildLoops() {
        return childLoops;
    }

    public IR_BaseBlock getHeader() {
        return loopHeader;
    }

    public Loop getParentLoop() {
        return parentLoop;
    }

    public void setParentLoop(Loop parentLoop) {
        this.parentLoop = parentLoop;
    }

    public boolean isInLoop(IR_BaseBlock block) {
        return loopBody.contains(block);
    }

    public List<IR_BaseBlock> getLoopBody() {
        return loopBody;
    }

}
